home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.4 Applications 1997 August / SGI IRIX 6.4 Applications 1997 August.iso / dist / gateway.idb / usr / WebFace / Source / 20-NetworkServices / dns / named-config.frm.z / named-config.frm
Encoding:
Text File  |  1997-07-30  |  17.3 KB  |  606 lines

  1. #!/usr/bin/perl5
  2. #
  3. # named-config.cgi
  4. #
  5. # Copyright 1988-1996 Silicon Graphics, Inc.
  6. # All rights reserved.
  7. #
  8. # This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  9. # the contents of this file may not be disclosed to third parties, copied or
  10. # duplicated in any form, in whole or in part, without the prior written
  11. # permission of Silicon Graphics, Inc.
  12. #
  13. # RESTRICTED RIGHTS LEGEND:
  14. # Use, duplication or disclosure by the Government is subject to restrictions
  15. # as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  16. # and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  17. # successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  18. # rights reserved under the Copyright Laws of the United States.
  19. #
  20. # $Id: named-config.frm,v 1.47 1997/06/19 22:25:09 shotes Exp $
  21.  
  22. require "/usr/OnRamp/lib/OnRamp.pm";
  23. require "/usr/OnRamp/lib/java.pm";
  24.  
  25. $conf = "/etc/named.boot";
  26. $dummy = "/etc/named.boot.dummy";
  27. $myname = "named-config.cgi";
  28. $title = "Domain Name Server";
  29.  
  30. # note; this does not match AccountForm prototype
  31. # since it also requires the runOK() routine.
  32. # also, testDomain is unique in that it allows
  33. # IN-ADDR.ARPA domains...
  34. $js_main =
  35. "$js_error_box
  36. $js_hostname
  37. $js_iplist
  38. $js_ip
  39. which = \"none\";
  40. function runSubmit() {
  41.     if(which == \"add\") return runAdd();
  42.     if(which == \"edit\") return runEdit();
  43.     if(which == \"delete\") return runDelete();
  44.     if(which == \"ok\") return runOK();
  45.     return (true);
  46. }    
  47. function markAdd() { which = \"add\"; }
  48. function markEdit() { which = \"edit\"; }
  49. function markDelete() { which = \"delete\"; }
  50. function markOK() { which = \"ok\"; }
  51. function markOther() { which = \"none\"; }
  52. function runAdd()  {
  53.     form = document.DNSForm;
  54.     if (!testDomain(form.newDomain)) return (false);
  55.     return (true);
  56. }
  57. function runEdit()  {
  58.     Ctrl = document.DNSForm.chosen;
  59.     none = true;
  60.     for(i = 0; i < Ctrl.length; i++) { if (Ctrl.options[i].selected) { none = false; break; } }
  61.     if(none) { errorBox (Ctrl, \"To edit an existing domain, first select a domain \\nfrom the list, then click the edit button.\"); return (false); }
  62.     return (true);
  63. }
  64. function runDelete()  {
  65.     Ctrl = document.DNSForm.chosen;
  66.     none = true;
  67.     for(j = 0; j < Ctrl.length; j++) { if (Ctrl.options[j].selected) { none = false; break; } }
  68.     if(none) { errorBox (Ctrl, \"To delete an existing domain, first select a domain \\nfrom the list, then click the delete button.\"); return (false); }
  69.     return (true);
  70. }
  71. function runOK()  {
  72.     form = document.DNSForm;
  73.     if (!testIPList(form.forwarders, \"forwarder\")) return (false);
  74.     return (true);
  75. }
  76.  
  77. function createArray(num) {
  78.     this.length = num;
  79.     for (var j = 0; j < num; j++) { this[j] = 0; }
  80. }
  81.  
  82. function testDomain(Ctrl) {
  83.     nums = \"0123456789\";
  84.     arpa_num = 0; i = 0;
  85.     st_num = false;
  86.  
  87.     p_places = new createArray(4);
  88.  
  89.     if (Ctrl.value == \"\") { 
  90.     errorBox (Ctrl, \"To add a new domain, first enter \\nthe domain name.\"); 
  91.     return (false); 
  92.     }
  93.    
  94.     for(i=0; i<nums.length; i++)
  95.     if (Ctrl.value.charAt(0) == nums.charAt(i)) st_num = true; 
  96.  
  97.     if (st_num) {
  98.     arpa_num = 0;
  99.     for(i=0; i<Ctrl.value.length; i++)
  100.         if (Ctrl.value.charAt(i) == \"I\" || Ctrl.value.charAt(i) == \"i\") arpa_num = i;
  101.     if (arpa_num == 0) { 
  102.         errorBox (Ctrl, \"The domain name \" + Ctrl.value + \"\\nis invalid.\"); 
  103.         return (false); 
  104.     }
  105.     rev_ip = Ctrl.value.substring(0, arpa_num - 1);
  106.     arpa_str = Ctrl.value.substring(arpa_num, Ctrl.value.length);
  107.  
  108.     arpa_str = arpa_str.toUpperCase();
  109.     if (arpa_str != \"IN-ADDR.ARPA\") {
  110.         errorBox (Ctrl, \"The domain name \" + Ctrl.value + \"\\nis invalid.\");
  111.         return (false);
  112.     }
  113.  
  114.     p_places[0] = -1;
  115.     num_periods = 0;
  116.     for (i=0; i<rev_ip.length; i++) {
  117.         if (rev_ip.charAt(i) == \".\") {
  118.         num_periods++;
  119.         p_places[num_periods] = i;
  120.         }
  121.     }
  122.  
  123.     unrev_ip = rev_ip.substring(p_places[num_periods] + 1, rev_ip.length);
  124.     for (i=num_periods; i>=1; i--)
  125.         unrev_ip = unrev_ip + \".\" + rev_ip.substring(p_places[i-1]+1,p_places[i]); 
  126.  
  127.     if (!testIPaddress(unrev_ip, false)) {
  128.         errorBox(Ctrl, \"The domain name \" + Ctrl.value + \"\\nis invalid.\");
  129.         return (false);
  130.     }
  131.  
  132.     } else {
  133.     if (!testHostname(Ctrl, Ctrl.value, \"domain name\", 0))
  134.         return (false); 
  135.     }
  136.     return (true);
  137. }";
  138.  
  139. $js_add =
  140. "$js_standard
  141. $js_error_box
  142. $js_filename
  143. $js_ip
  144. $js_iplist
  145. function checkForm(form)  {
  146.     if (!testFilename(form.newFile, \"file name\")) return (false);
  147.     if (form.list.value == \"\" && form.newType.options[1].selected) {
  148.         errorBox (form.list, \"A list of server addresses is \"
  149.             + \"required \\nfor the secondary domain.\");
  150.         return (false);
  151.     }
  152.     if (!testIPList(form.list, \"server address\")) return (false);
  153.     return (true);
  154. }";
  155.  
  156. $js_edit = 
  157. "$js_standard
  158. $js_error_box
  159. $js_filename
  160. $js_ip
  161. $js_iplist
  162. function checkForm(form)  {
  163.     if (!testFilename(form.newFile, \"file name\")) return (false);
  164.     if (form.list.value == \"\" && form.type.options[1].selected) {
  165.         errorBox (form.list, \"A list of server addresses is \"
  166.             + \"required \\nfor the secondary domain.\");
  167.         return (false);
  168.     }
  169.     if (!testIPList(form.list, \"server address\")) return (false);
  170.     return (true);
  171. }";
  172.  
  173.  
  174. print "Content-type: text/html\n\n";
  175.  
  176. &get_fields;
  177.  
  178. $srv_on = get_config("named");
  179.  
  180. $edit = 0;
  181. $delete = 0;
  182.  
  183. &getDomains;
  184.  
  185. if (%fld) {
  186.     $fld{'chosen'} =~ /([\w.-]+)/;
  187.     $fld{'chosen'} = $1;
  188.  
  189.     $help = $document_root . $ENV{"SCRIPT_NAME"};
  190.     $help =~ s/cgi$/hlp/;
  191.     exec $help if ($fld{'help'} eq "Help");
  192.  
  193.     if ($fld{'doit'} eq 'Ok') {
  194.         if ($srv_on ne $fld{'server'}) { &changeStatus; }
  195.         if ($fld{'delFile'}) { &delete($fld{'delFile'}); }
  196.         &checkForwarders;
  197.         &checkSlave;
  198.         if (!$message) { 
  199.             if (!$fld{'newDomain'}) { $message = "No changes made."; }
  200.             else { $message = qq|To add a new domain, click the "Add New Domain"
  201.                    button.|; }
  202.         }
  203.     }
  204.     elsif ($fld{'add'}) { 
  205.         &formValid_add;
  206.         $val{'domain'} = $fld{'newDomain'};
  207.         $val{'type'} = $type; 
  208.         &getAdd; 
  209.     }
  210.     elsif ($fld{'delete'}) {
  211.         &error(0,"No domain selected.") if !$fld{'chosen'};
  212.         $message = qq|Click "Ok" to save changes.|; 
  213.         $delete = 1; 
  214.     }
  215.     elsif ($fld{'doAdd'} eq 'Ok') { &formValid_doAdd; &addDomain; &getDomains; }
  216.     elsif ($fld{'doEdit'} eq 'Ok') { &formValid_doEdit; &editDomain; &getDomains; }
  217.     elsif ($fld{'edit'}) {
  218.         &error(0,"No domain selected.") if !$fld{'chosen'}; 
  219.         &getDomains($fld{'chosen'});
  220.         &putEdit;
  221.         &getEdit;
  222.         $edit = 1;
  223.     }
  224.     else { $message = "Use buttons to submit form."; &generic; exit 0; }
  225. }
  226.  
  227. if (($fld{'add'} ne 'Add New Domain') && ($edit == 0)) {
  228.     if (-e "/usr/sbin/named") { &generic; }
  229.     else { 
  230.         &title_block($title);
  231.         &header_block($title);
  232.         print "<i>The domain name server software is not installed on this
  233.         machine.  Install subsystem </i><b>eoe.sw.named</b><i>
  234.         from the distribution CD.</i>";
  235.     }   
  236. }
  237.  
  238. sub checkSlave {
  239.     if ($val{'slave'} ne $fld{'slave'}) {
  240.         if ($fld{'slave'} eq 'Yes') {
  241.             open(OUT,">> $conf");
  242.             print OUT "slave\n";
  243.             close(OUT);
  244.             $val{'slave'} = 'Yes';
  245.             $message = "Dynamic creation of direct links disabled.";
  246.         } else {
  247.             open(IN,"< $conf");
  248.             open(OUT,"> $dummy");
  249.             while(<IN>) {
  250.                 @items = split(/\s+/);
  251.                 if ($items[0] ne 'slave') { print OUT $_; }
  252.             }
  253.             close(IN);
  254.             close(OUT);
  255.             rename($dummy,$conf);
  256.             $val{'slave'} = 'No';
  257.             $message = "Dynamic creation of direct links enabled.";
  258.         }
  259.     }
  260. }
  261.  
  262. sub changeStatus {
  263.     if($fld{'server'} eq 'Yes') { 
  264.     system("/etc/chkconfig", "named", "on");
  265.     system("/usr/sbin/named.restart");
  266.         $srv_on = "Yes"; 
  267.         $message = "Name server enabled.";
  268.     }
  269.     else { 
  270.     system("/etc/chkconfig", "named", "off");
  271.     system("/etc/killall", "named");
  272.         $srv_on = "No";
  273.         $message = "Name server disabled.";
  274.     }
  275. }
  276.  
  277. sub formValid_add {
  278.     &error(0,"Cannot add duplicate domain name.") 
  279.         if grep($_ eq $fld{'newDomain'},@domainList);
  280.     &error(0,"Invalid domain name.") 
  281.     if $fld{'newDomain'} =~ /^\s+$/;
  282. #    if (! ( $fld{'newDomain'} =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)\.in-addr\.arpa/ )) {
  283. #        &error(0,"Invalid domain name.") if &check_hostname($fld{'newDomain'});
  284. #    } else {
  285. #        $reverse = "$4.$3.$2.$1";
  286. #        &error(0,"Invalid IP address: $reverse.") if &check_ipaddr($reverse);
  287. #    }
  288. }
  289.  
  290. sub formValid_doAdd {
  291.     my $erval = &check_fname($fld{'newFile'});
  292.     &error(1,$erval) if $erval;
  293.  
  294.     if ($fld{'newType'} eq 'secondary') {
  295.         &error(1,"Server addresses required for secondary domain.") 
  296.             if !$fld{'list'};
  297.         @list = split(/[\n\s]+/,$fld{'list'});
  298.         foreach $arg (@list) {
  299.             &error(1,"Invalid IP address: $arg.") if &check_ipaddr($arg);
  300.         }
  301.     }
  302. }
  303.  
  304. sub formValid_doEdit {
  305.     my $erval = &check_fname($fld{'newFile'});
  306.     &error(2,$erval) if $erval;
  307.  
  308.     if ($fld{'type'} eq 'secondary') {
  309.         &error(2,"Server addresses required for secondary domain.") 
  310.             if !$fld{'list'};
  311.         @list = split(/[\n\s]+/,$fld{'list'});
  312.         foreach $arg (@list) {
  313.             &error(2,"Invalid IP address: $arg.") if &check_ipaddr($arg);
  314.         }
  315.     }
  316. }
  317.  
  318. sub error {
  319.     $mes = $_[1];
  320.     $send = $_[0];
  321.     &error_block($mes);
  322.     %val = %fld;
  323.     if ($send == 0) { &generic; }
  324.     elsif ($send == 1) { &getAdd; }
  325.     elsif ($send == 2) { &getEdit; }
  326.     exit 0;
  327. }
  328.  
  329. sub editDomain {
  330.     open(IN,"< $conf");
  331.     open(OUT,"> $dummy");
  332.  
  333.     while(<IN>) {
  334.         $line = $_;
  335.         @items = split(/\s+/,$line);
  336.         if ($items[1] ne $fld{'chosen'}) { print OUT $line; next; }
  337.         else { 
  338.             print OUT "# $line";
  339.         }   
  340.     }
  341.  
  342.     $numTab1 = 2 - length($fld{'type'})/8;
  343.     $numTab2 = 4 - length($fld{'domain'})/8;
  344.  
  345.     print OUT $fld{'type'};
  346.  
  347.     for ($i=0;$i<$numTab1;$i++) { print OUT "\t"; }
  348.     print OUT $fld{'chosen'};
  349.     if ($fld{'type'} eq 'primary') {
  350.         for ($i=0;$i<$numTab2;$i++) { print OUT "\t"; }
  351.     } else {
  352.         print OUT " ";
  353.         foreach $arg (@list) {
  354.             print OUT "$arg ";
  355.         }
  356.     }
  357.     print OUT "$fld{'newFile'}\n";    
  358.  
  359.     close(IN);
  360.     close(OUT);
  361.     rename($dummy, $conf);
  362.     $message = "Domain edited.";
  363. }
  364.  
  365. sub putEdit {
  366.     $val{'newFile'} = $file;
  367.     $val{'list'} = "";
  368.     foreach $arg (@listServe) {
  369.         $val{'list'} .= "$arg\n";
  370.     }
  371. }
  372.  
  373. sub getEdit {
  374.     $num = $_[0];
  375.  
  376.     &js_title_block($title,$js_edit);
  377.     &header_block("Edit Domain");
  378.  
  379.     print "<form name=StandardForm action=$myname method=post onSubmit=\"return runSubmit()\">";
  380.     print "<center><table>";
  381.  
  382.     print "<input type=hidden name=chosen value=$fld{'chosen'}>";
  383.     print "<input type=hidden name=type value=$val{'type'}>";
  384.  
  385.     print "<tr><th align=left>Domain name:</th><td><tt>$fld{'chosen'}</tt></td></tr>";
  386.     print "<tr><th align=left>Name server type:</th><td><tt>$val{'type'}</tt></td></tr>";
  387.  
  388.     print "<tr><th align=left>File name for domain information:</th><td>";
  389.     print &text("newFile",$val{'newFile'},21);
  390.     print "</td></tr>\n";
  391.  
  392.     if ($fld{'type'.$num} ne 'primary') {
  393.         print "<tr><th align=left valign=top>List of server addresses:</th>";
  394.         print "<td><textarea name=list rows=5 cols=20>";
  395.         print $val{'list'};
  396.         print "</textarea></td>";
  397.         print "</tr>\n";
  398.     }
  399.     print "</table></center><br>";
  400.  
  401.     print "<i>  Note:  server address list required only for secondary domains.</i><br><br>";
  402.  
  403.     print &js_buttons('doEdit','Ok','onClick="markOK()"','onClick="markOther()"');
  404.  
  405.     print "</form>";
  406. }
  407.  
  408. sub delete {
  409.     $num = $_[0];
  410.  
  411.     open(IN,"< $conf");
  412.     open(OUT,"> $dummy");
  413.  
  414.     while(<IN>) {
  415.         @items = split(/\s+/);
  416.         if ($items[1] eq $_[0]) { print OUT "# $_"; }
  417.         else { print OUT $_; }
  418.     }
  419.     close(IN);
  420.     close(OUT);
  421.     rename($dummy, $conf);
  422.     $message = "Domain deleted.";
  423. }
  424.      
  425. sub addDomain {
  426.     $numTab1 = 2 - length($fld{'newType'})/8;
  427.     $numTab2 = 4 - length($fld{'domain'})/8;
  428.  
  429.     open(OUT,">> $conf");
  430.     print OUT $fld{'newType'};
  431.     for ($i=0;$i<$numTab1;$i++) { print OUT "\t"; }
  432.     print OUT $fld{'domain'};
  433.     if ($fld{'newType'} eq 'primary') {
  434.         for ($i=0;$i<$numTab2;$i++) { print OUT "\t"; }
  435.     } else {
  436.         print OUT " ";
  437.         foreach $arg (@list) {
  438.             print OUT "$arg ";
  439.         }
  440.     }
  441.     print OUT "$fld{'newFile'}\n";
  442.  
  443.     close(OUT);
  444.     $message = "$fld{'domain'} domain added.";
  445. }
  446.  
  447. sub turnOn  { 
  448.     system("/etc/chkconfig", "named", "on");
  449.     $srv_on = 'Yes'; 
  450.     $message = "Named enabled";
  451. }
  452. sub turnOff { 
  453.     system("/etc/chkconfig", "named", "off");
  454.     $srv_on = 'No'; 
  455.     $message = "Named disabled";
  456. }
  457.  
  458. sub getDomains {
  459.     $getDomain = $_[0];
  460.     undef @domainList;
  461.     undef @listServe;
  462.     undef @forwarders, $forwarders;
  463.     $val{'slave'} = "No";
  464.  
  465.     open(IN,"< $conf");
  466.  
  467.     $i = 0;
  468.     while(<IN>) {
  469.         $line = $_;
  470.         @items = split(/\s+/,$line);
  471.         $domain = $items[1];
  472.  
  473.         if ($items[0] eq 'slave') { $val{'slave'} = "Yes"; }
  474.         elsif ($items[0] eq 'forwarders') { 
  475.             for ($i=1;$i<=$#items;$i++) { 
  476.                 push(@forwarders,$items[$i]);
  477.             }
  478.         } elsif ($items[0] eq 'primary' || $items[0] eq 'secondary') {
  479.             push(@domainList,$domain);
  480.             if ($getDomain eq $domain) {
  481.                 $val{'type'} = $items[0];
  482.                 $file = $items[$#items];
  483.                 if ($val{'type'} eq 'secondary') {
  484.                     for ($i=2;$i<$#items;$i++) { push(@listServe,$items[$i]); }
  485.                 }
  486.             }
  487.         } else { next; } # cache not supported yet
  488.     }
  489.     close(IN);
  490.     $val{'forwarders'} = join("\n",@forwarders);  
  491. }
  492.  
  493. sub checkForwarders {
  494.     &getDomains;
  495.     @list = split(/[\n\s]+/,$fld{'forwarders'});
  496.     $newForwarders = join("\n",@list);
  497.     if ($newForwarders ne $val{'forwarders'}) { 
  498.         open(IN,"< $conf");
  499.         open(OUT,"> $dummy");
  500.         while(<IN>) {
  501.             @items = split(/\s+/);
  502.             if ($items[0] ne 'forwarders') { print OUT $_; }
  503.             else { print OUT "# $_"; }
  504.         }
  505.         if (@list) {
  506.             print OUT "forwarders\t@list\n";
  507.         }
  508.         close(IN);
  509.         close(OUT);
  510.         rename($dummy, $conf);
  511.  
  512.         $val{'forwarders'} = join("\n",@list);
  513.     
  514.         $message = "List of other servers that can resolve names edited.";
  515.     }
  516.  
  517. sub getAdd {
  518.     &js_title_block($title,$js_add);
  519.     &header_block("Add New Domain");
  520.  
  521.     if (!$val{'newFile'}) { 
  522.         $val{'newFile'} = "/etc/named.d/db.".$val{'domain'}; 
  523.     }
  524.  
  525.     print "<form name=StandardForm action=$myname method=post onSubmit=\"return runSubmit()\">";
  526.     print "<center><table>";
  527.  
  528.     print qq|<input type=hidden name="domain" value=$val{'domain'}>|;
  529.  
  530.     print "<tr><th align=left>Domain name:</th><td><tt>$val{'domain'}</tt></td></tr>";
  531.     print "<tr><th align=left>Name server type:</th><td><tt>",
  532.         &select('newType',$val{'newType'},'primary','secondary'), "</tt></td></tr>";
  533.  
  534.     print "<tr><th align=left>File name for domain information:</th>";
  535.     print "<td>", &text("newFile",$val{'newFile'},21), "</td>";
  536.     print "</tr>\n";
  537.     
  538.     print "<tr><th align=left valign=top>List of server addresses:</th>";
  539.     print "<td><textarea name=list rows=5 cols=20>",
  540.            $val{'list'},"</textarea></td>";
  541.     print "</tr>\n";
  542.  
  543.     print "</table></center><br>";
  544.  
  545.     print "<i>  Note:  server address list required only for secondary domains.</i><br><br>";
  546.  
  547.     print &js_buttons('doAdd','Ok','onClick="markOK()"','onClick="markOther()"');
  548.  
  549.     print "</form>";
  550. }
  551.  
  552. sub generic {
  553.     &js_title_block($title,$js_main);
  554.     &header_block($title);
  555.  
  556.     $val{'newDomain'} = $fld{'newDomain'};
  557.  
  558.     print "<i>$message</i>\n";
  559.  
  560.     print "<form name=DNSForm action=$myname method=post onSubmit=\"return runSubmit()\">\n";
  561.  
  562.     if ($delete) { print "<input type=hidden name=delFile value=$fld{'chosen'}>\n"; }
  563.  
  564.     print "<center><table width=450>";
  565.     print "<tr><th align=left>Enable DNS server:</th><th align=left>\n";
  566.     print &radio('server',$srv_on,'Yes','No');
  567.     print "<br><br></th></tr>\n";
  568.  
  569.     print qq|<tr><th align=left><input type=submit name="add" 
  570.     value="Add New Domain" onClick="markAdd()"></th>\n|;
  571.     print qq|<td>|,&text("newDomain",$val{'newDomain'},19),qq|</td></tr>\n|;
  572.  
  573.     if ($delete) {
  574.         undef @locList;
  575.         foreach $arg (@domainList) {
  576.             if ($fld{'chosen'} ne $arg) { push(@locList,$arg); }
  577.         }
  578.     } else { @locList = @domainList; }
  579.  
  580.     print qq|<tr><th align=left><input type=submit name="edit" 
  581.     value="Edit Selected Domain" onClick="markEdit()"></th>\n|;
  582.     print qq|<td rowspan=2>|, &choice_list(*locList,"chosen",20), qq|</td></tr>\n|;
  583.  
  584.     print qq|<tr><th align=left><input type=submit name="delete" 
  585.     value="Delete Selected Domain" onClick="markDelete()"></th></tr>\n|;
  586.  
  587.     print "<tr><td> </td></tr>\n";
  588.  
  589.     print "<tr><th align=left valign=top>Other servers to contact if <br>
  590.     name cannot be resolved:</th><td>\n";
  591.  
  592.     print "<textarea name=forwarders rows=6 cols=18>$val{'forwarders'}</textarea></td></tr>\n";
  593.  
  594.     print "<tr><th align=left>Limit contact hosts to above:</th><th align=left>\n";
  595.     print &radio('slave',$val{'slave'},'Yes','No');
  596.     print "</th></tr>"; 
  597.  
  598.     print "</table></center><br>\n";    
  599.  
  600.     print &js_buttons('doit','Ok','onClick="markOK()"','onClick="markOther()"');
  601.  
  602.     print "</form></body></html>";
  603. }
  604.  
  605.